package com.xiaoxin.xinlikesystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoxin.xinlikesystem.constant.ThumbConstant;
import com.xiaoxin.xinlikesystem.exception.ErrorCode;
import com.xiaoxin.xinlikesystem.exception.ThrowUtils;
import com.xiaoxin.xinlikesystem.model.entity.Blog;
import com.xiaoxin.xinlikesystem.model.entity.User;
import com.xiaoxin.xinlikesystem.model.vo.Blog.BlogVO;
import com.xiaoxin.xinlikesystem.service.BlogService;
import com.xiaoxin.xinlikesystem.mapper.BlogMapper;
import com.xiaoxin.xinlikesystem.service.ThumbService;
import com.xiaoxin.xinlikesystem.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Xiaoxin
 * @description 针对表【blog(博客表)】的数据库操作Service实现
 * @createDate 2025-05-10 14:00:17
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog>
        implements BlogService {

    @Resource
    private UserService userService;

    @Resource
    @Lazy
    private ThumbService thumbService;


    /**
     * 获取博客
     *
     * @param blogId  博客ID
     * @param request 请求
     * @return 博客内容
     */
    @Override
    public BlogVO getBlogVOById(long blogId, HttpServletRequest request) {
        // TODO 博客是否公开可看
        // 1. 校验参数
        Blog blog = this.getById(blogId);
        ThrowUtils.throwIf(blog == null, ErrorCode.NOT_FOUND_ERROR, "博客不存在");

        // 2. 返回博客包装类
        User loginUser = userService.getLoginUser(request);
        return getBlogVO(blog, loginUser);
    }


    /**
     * 获取博客（包装类），如果已经登陆则获取当前用户是否已经点赞
     *
     * @param blog      文章
     * @param loginUser 登录用户
     * @return 返回博客包装类
     */
    @Override
    public BlogVO getBlogVO(Blog blog, User loginUser) {
        // 1. 转换博客为包装类
        BlogVO blogVO = new BlogVO();
        BeanUtil.copyProperties(blog, blogVO);

        // 2. 如果登录状态不为空，则填充当前用户是否点赞
        if (loginUser == null) {
            return blogVO;
        }
        Long thumbId = thumbService.hasThumb(blog.getId(), loginUser.getId());
        blogVO.setHasThumb(thumbId != null);
        return blogVO;
    }


    /**
     * 按页获取博客（包装类）
     *
     * @param current  页码
     * @param pageSize 页大小
     * @return 返回博客页查询
     */
    @Override
    public Page<BlogVO> getBlogVOPage(long current, long pageSize, HttpServletRequest request) {
        // 1. 分页查询博客数据
        Page<Blog> blogPage = new Page<>(current, pageSize);
        Page<Blog> pageResult = this.page(blogPage);
        List<Blog> blogList = pageResult.getRecords();

        // 2. 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        // 3. 查询用户是否进行了点赞
        Map<Long, Boolean> blogIdHasThumbMap;
        if (ObjUtil.isNotEmpty(loginUser)) {
            // 遍历博客列表，检查用户是否点赞
            blogIdHasThumbMap = blogList.stream()
                    .map(Blog::getId)
                    .collect(Collectors.toMap(
                            blogId -> blogId,
                            blogId -> thumbService.hasThumb(blogId, loginUser.getId()) != null
                    ));
        } else {
            blogIdHasThumbMap = new HashMap<>();
        }

        // 4. 封装成 BlogVO 列表
        List<BlogVO> blogVOList = blogList.stream()
                .map(blog -> {
                    BlogVO blogVO = BeanUtil.copyProperties(blog, BlogVO.class);
                    blogVO.setHasThumb(blogIdHasThumbMap.getOrDefault(blog.getId(), false));
                    return blogVO;
                }).toList();

        // 5. 构建分页结果对象（保持页码等一致）
        Page<BlogVO> blogVOPage = new Page<>(pageResult.getCurrent(), pageSize, pageResult.getTotal());
        blogVOPage.setRecords(blogVOList);

        return blogVOPage;
    }


}




